package com.mindata.blockchain.socket.handler.server.block;

import com.mindata.blockchain.ApplicationContextProvider;
import com.mindata.blockchain.block.block.Block;
import com.mindata.blockchain.block.block.DGLBlock;
import com.mindata.blockchain.block.check.CheckerManager;
import com.mindata.blockchain.common.CommonUtil;
import com.mindata.blockchain.common.Commonvalue;
import com.mindata.blockchain.socket.DGL.msg.DGLVotePreMsg;
import com.mindata.blockchain.socket.DGL.queue.DGLPreMsgQueue;
import com.mindata.blockchain.socket.base.AbstractBlockHandler;
import com.mindata.blockchain.socket.body.rpc.RpcCheckBlockBody;
import com.mindata.blockchain.socket.body.rpc.RpcDGLBlockBody;
import com.mindata.blockchain.socket.common.msg.MsgType;
import com.mindata.blockchain.socket.common.queue.IntroAddBlockQueue;
import com.mindata.blockchain.socket.common.queue.base.MsgQueueManager;
import com.mindata.blockchain.socket.packet.BlockPacket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.ChannelContext;


/**
 * @author maltyshane
 */
public class DGLGenerateBlockRequestHandler extends AbstractBlockHandler<RpcDGLBlockBody> {
    private Logger logger = LoggerFactory.getLogger(DGLGenerateBlockRequestHandler.class);
    DGLPreMsgQueue dglPreMsgQueue = ApplicationContextProvider.getBean(DGLPreMsgQueue.class);
    Commonvalue commonvalue = ApplicationContextProvider.getBean(Commonvalue.class);
    private IntroAddBlockQueue introAddBlockQueue = ApplicationContextProvider.getBean(IntroAddBlockQueue.class);

    @Override
    public Class<RpcDGLBlockBody> bodyClass() {
        return RpcDGLBlockBody.class;
    }

    @Override
    public Object handler(BlockPacket packet, RpcDGLBlockBody rpcBlockBody, ChannelContext channelContext) {
        DGLBlock dglBlock = rpcBlockBody.getDglBlock();
        if (introAddBlockQueue.dglBlockConcurrentHashMap.containsKey(dglBlock.getDglBlockHeader().getNumber())) {
            return null;
        }
        logger.info("收到来自于<{}><请求生成DGLBlock>消息，dglblock信息为[{}]", rpcBlockBody.getAppId(), dglBlock.getHash());

//        if (dglPreMsgQueue.findPreMsgByHash(dglBlock.getHash()) != null) {
//            logger.warn("已经收到过请求生成DGLBlock消息");
//            return null;
//        }
        CheckerManager checkerManager = ApplicationContextProvider.getBean(CheckerManager.class);
        int codestate = 0;
        RpcCheckBlockBody rpcCheckBlockBody;
        //对区块的基本信息进行校验，校验通过后进入pbft的Pre队列
        for (Block block : dglBlock.getBlockList()) {
            //TODO 校验失败
            rpcCheckBlockBody = checkerManager.checkBlock(block);
            codestate = rpcCheckBlockBody.getCode();
            if (codestate != 0) {
                logger.info("校验失败:{}", rpcCheckBlockBody);
                return null;
            }
        }
        DGLVotePreMsg dglVotePreMsg = new DGLVotePreMsg();
        dglVotePreMsg.setDglBlock(dglBlock);
        dglVotePreMsg.setVoteType(MsgType.DLGPREPREPARE);
        dglVotePreMsg.setNumber(dglBlock.getDglBlockHeader().getNumber());
        dglVotePreMsg.setAppId(rpcBlockBody.getAppId());
        dglVotePreMsg.setHash(dglBlock.getHash());
        dglVotePreMsg.setAgree(true);
        logger.error("global出块时间: {}", CommonUtil.getNow());
        //将消息推入PrePrepare队列
//        logger.warn("{} : {}生成DGLVotePreMsg 并push进入DGLPreMsgQueue", commonvalue.getMygroupid(), commonvalue.getNodeIndex());
        ApplicationContextProvider.getBean(MsgQueueManager.class).pushMsg(dglVotePreMsg);
        return null;
    }
}
